!===============Programa que encontra raízes de uma função==============

PROGRAM exerC

!=======================================================================

IMPLICIT NONE

!=======================Declaração de variáveis=========================

      REAL(8) :: f, der_f, med
      !Define um vetor cujas entradas são os chutes iniciais das raízes
      REAL(8), DIMENSION(6) :: roots
      REAL(8), ALLOCATABLE, DIMENSION(:) :: x
      REAL(8), ALLOCATABLE, DIMENSION(:,:) :: tab
      INTEGER :: n_iter, I, J, posi
      !Formato a ser usado no write que escreve no arquivo
      CHARACTER(LEN=*), PARAMETER :: FMT1 = "(10F12.7)"

!======================Define os chutes iniciais========================

      !Aos pares, cada par procura uma raiz entre os dois valores
      roots = (/-0.7d0, -0.4d0, 0.2d0, 0.35d0, 0.6d0, 0.7d0/)

!================Abertura de arquivos e leitura de dados================

      OPEN(UNIT=10, FILE='tab3_out.dat', STATUS='unknown')

      WRITE(*,*) "Entre com o número de iterações a serem realizadas"
      READ(*,*) n_iter

      ALLOCATE(tab(10,n_iter),x(n_iter+2))

      x = 0.0d0
      tab = 0.0d0

!==================Cálculo das raízes por busca direta=================

      J = 1
      posi = 2
      !Do que percorre os chutes das raízes
      DO WHILE ((J+1) <= 6)
            x(1) = roots(J)
            x(2) = roots(J+1)

            !Itera para o intervalo chutado
            DO I=1,n_iter
                  med = (x(I) + x(I+1)) / 2.0d0
                  IF ((f(x(I+1))*f(med)) < 0) THEN
                        x(I+2) = x(I+1)
                        x(I+1) = med
                  ELSE
                        x(I+1) = x(I)
                        x(I+2) = med
                  END IF
                  tab(1,I) = I
                  tab(posi,I) = med
            END DO

            J = J + 2
            posi = posi + 1
      END DO

!==================Cálculo das raízes por Newton-Raphson================

      J = 1
      posi = 5
      !Do que percorre os chutes das raízes
      DO WHILE ((J+1) <= 6)
            tab(posi,1) = roots(J)

            !Itera para o intervalo chutado
            DO I=1,n_iter
                  tab(posi,I+1) = tab(posi,I) - (f(tab(posi,I))/&
                  &der_f(tab(posi,I)))
            END DO

            J = J + 2
            posi = posi + 1
      END DO



!===============Cálculo das raízes pelo método da secante===============

      J = 1
      posi = 8
      !Do que percorre os chutes das raízes
      DO WHILE ((J+1) <= 6)
            tab(posi,1) = roots(J)
            tab(posi,2) = roots(J+1)

            !Itera para o intervalo chutado
            DO I=2,(n_iter-1)
                  tab(posi,I+1) = tab(posi,I)-f(tab(posi,I))*&
                  &((tab(posi,I)-tab(posi,I-1))/(f(tab(posi,I))&
                  &-f(tab(posi,I-1))))
            END DO

            J = J + 2
            posi = posi + 1
      END DO

!=====================Escreve a tabela no arquivo=======================

      WRITE(10,FMT1) tab

!=======================================================================

END PROGRAM exerC

!=======================================================================


!========================Subrotinas e Funções===========================

!Calcula o valor da função no ponto x
REAL(8) FUNCTION f(x)
      IMPLICIT NONE

      REAL(8) :: x

      f = 18.0d0*x**3.0d0 - 9.0d0*x**2.0d0 - 5.0d0*x + 2.0d0
END FUNCTION f

!Calcula o valor da derivada de f no ponto x
REAL(8) FUNCTION der_f(x)
      IMPLICIT NONE

      REAL(8) :: x

      der_f = 54.0d0*x**2.0d0 - 18.0d0*x - 5.0d0
END FUNCTION

!=======================================================================
